home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Tool Chest / Development Tools & Languages / Dylan Related / Mindy / Mindy 1.2 - portable sources / interp / handler.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-15  |  5.0 KB  |  185 lines  |  [TEXT/ttxt]

  1. /**********************************************************************\
  2. *
  3. *  Copyright (c) 1994  Carnegie Mellon University
  4. *  All rights reserved.
  5. *  
  6. *  Use and copying of this software and preparation of derivative
  7. *  works based on this software are permitted, including commercial
  8. *  use, provided that the following conditions are observed:
  9. *  
  10. *  1. This copyright notice must be retained in full on any copies
  11. *     and on appropriate parts of any derivative works.
  12. *  2. Documentation (paper or online) accompanying any system that
  13. *     incorporates this software, or any part of it, must acknowledge
  14. *     the contribution of the Gwydion Project at Carnegie Mellon
  15. *     University.
  16. *  
  17. *  This software is made available "as is".  Neither the authors nor
  18. *  Carnegie Mellon University make any warranty about the software,
  19. *  its performance, or its conformity to any specification.
  20. *  
  21. *  Bug reports, questions, comments, and suggestions should be sent by
  22. *  E-mail to the Internet address "gwydion-bugs@cs.cmu.edu".
  23. *
  24. ***********************************************************************
  25. *
  26. * $Header: handler.c,v 1.7 94/10/05 21:02:06 nkramer Exp $
  27. *
  28. * This file implements the low level support for exception handlers.
  29. *
  30. \**********************************************************************/
  31.  
  32. #include "../compat/std-c.h"
  33.  
  34. #include "mindy.h"
  35. #include "class.h"
  36. #include "gc.h"
  37. #include "obj.h"
  38. #include "def.h"
  39. #include "thread.h"
  40. #include "func.h"
  41. #include "list.h"
  42. #include "bool.h"
  43. #include "sym.h"
  44. #include "type.h"
  45. #include "handler.h"
  46.  
  47.  
  48. static obj_t obj_HandlerClass = NULL;
  49.  
  50. static void push_handler(obj_t method, struct thread *thread, obj_t *args)
  51. {
  52.     obj_t *old_sp = args-1;
  53.     obj_t type = args[0];
  54.     obj_t func = args[1];
  55.     obj_t test = args[2];
  56.     obj_t init_args = args[3];
  57.     obj_t handler = alloc(obj_HandlerClass, sizeof(struct handler));
  58.  
  59.     HANDLER(handler)->type = type;
  60.     HANDLER(handler)->function = func;
  61.     HANDLER(handler)->test = test;
  62.     HANDLER(handler)->init_args = init_args;
  63.     HANDLER(handler)->next = thread->handlers;
  64.     thread->handlers = handler;
  65.  
  66.     thread->sp = old_sp;
  67.     do_return(thread, old_sp, old_sp);
  68. }
  69.  
  70. static void current_handler(struct thread *thread, int nargs)
  71. {
  72.     obj_t *old_sp = thread->sp - 1;
  73.  
  74.     assert(nargs == 0);
  75.     *old_sp = thread->handlers;
  76.  
  77.     do_return(thread, old_sp, old_sp);
  78. }
  79.  
  80. static obj_t handler_type(obj_t handler)
  81. {
  82.     return HANDLER(handler)->type;
  83. }
  84.  
  85. static obj_t handler_function(obj_t handler)
  86. {
  87.     return HANDLER(handler)->function;
  88. }
  89.  
  90. static obj_t handler_test(obj_t handler)
  91. {
  92.     return HANDLER(handler)->test;
  93. }
  94.  
  95. static obj_t handler_init_args(obj_t handler)
  96. {
  97.     return HANDLER(handler)->init_args;
  98. }
  99.  
  100. static obj_t handler_next(obj_t handler)
  101. {
  102.     return HANDLER(handler)->next;
  103. }
  104.  
  105. static void pop_handler(struct thread *thread, int nargs)
  106. {
  107.     obj_t *old_sp = thread->sp - 1;
  108.  
  109.     assert(nargs == 0);
  110.  
  111.     thread->handlers = HANDLER(thread->handlers)->next;
  112.  
  113.     thread->sp = old_sp;
  114.     do_return(thread, old_sp, old_sp);
  115. }
  116.  
  117.  
  118.  
  119. /* GC stuff. */
  120.  
  121. static int scav_handler(struct object *obj)
  122. {
  123.     struct handler *handler = (struct handler *)obj;
  124.  
  125.     scavenge(&handler->type);
  126.     scavenge(&handler->function);
  127.     scavenge(&handler->test);
  128.     scavenge(&handler->init_args);
  129.     scavenge(&handler->next);
  130.  
  131.     return sizeof(struct handler);
  132. }
  133.  
  134. static obj_t trans_handler(obj_t handler)
  135. {
  136.     return transport(handler, sizeof(struct handler));
  137. }
  138.  
  139. void scavenge_handler_roots(void)
  140. {
  141.     scavenge(&obj_HandlerClass);
  142. }
  143.  
  144.  
  145. /* Init stuff. */
  146.  
  147. void make_handler_classes(void)
  148. {
  149.     obj_HandlerClass = make_builtin_class(scav_handler, trans_handler);
  150. }
  151.  
  152. void init_handler_classes(void)
  153. {
  154.     init_builtin_class(obj_HandlerClass, "<handler>", obj_ObjectClass, NULL);
  155. }
  156.  
  157. void init_handler_functions(void)
  158. {
  159.     define_constant("push-handler",
  160.             make_raw_method("push-handler",
  161.                     list2(obj_TypeClass, obj_FunctionClass),
  162.                     FALSE,
  163.                     list2(pair(symbol("test"), obj_False),
  164.                       pair(symbol("init-arguments"),
  165.                            obj_Nil)),
  166.                     FALSE, obj_Nil, obj_False, push_handler));
  167.     define_constant("current-handler",
  168.             make_raw_function("current-handler", 0, FALSE, obj_False,
  169.                       FALSE, list1(obj_HandlerClass),
  170.                       obj_False, current_handler));
  171.     define_function("handler-type", list1(obj_HandlerClass), FALSE, obj_False,
  172.             FALSE, obj_ObjectClass, handler_type);
  173.     define_function("handler-function", list1(obj_HandlerClass), FALSE,
  174.             obj_False, FALSE, obj_ObjectClass, handler_function);
  175.     define_function("handler-test", list1(obj_HandlerClass), FALSE, obj_False,
  176.             FALSE, obj_ObjectClass, handler_test);
  177.     define_function("handler-init-args", list1(obj_HandlerClass), FALSE,
  178.             obj_False, FALSE, obj_ObjectClass, handler_init_args);
  179.     define_function("handler-next", list1(obj_HandlerClass), FALSE, obj_False,
  180.             FALSE, obj_ObjectClass, handler_next);
  181.     define_constant("pop-handler",
  182.             make_raw_function("pop-handler", 0, FALSE, obj_False,
  183.                       FALSE, obj_Nil, obj_False, pop_handler));
  184. }
  185.